package recursive;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class FractalTree extends JPanel {
    //结点
    private List<ArrayList<Integer>> points = new ArrayList<>();
    //x坐标
    private ArrayList<Integer> xList = new ArrayList<>();
    //y坐标
    private ArrayList<Integer> yList = new ArrayList<>();
    private int max;
    private int min;

    public FractalTree(int max, int min) {
        this.max = max;
        this.min = min;
        getPoint(600, 760, max, 0.0);
    }

    //重写绘制方法
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < points.get(0).size(); i += 2) {
            g.drawLine(points.get(0).get(i), points.get(1).get(i), points.get(0).get(i + 1), points.get(1).get(i + 1));
        }
    }

    //递归获取所有结点和对应的坐标（起始x，起始y，最大值（长度逐步减小），）
    private void getPoint(int x, int y, int len, double e) {
        //停止条件，长度减小到最小值
        if (len <= min) {
            //将所有x坐标和y坐标添加到节点中
            points.add(xList);
            points.add(yList);
        } else {

            xList.add(x);
            yList.add(y);

            //角度计算
            int x1 = (int) (len * Math.cos(Math.PI / 2 - e) + x);
            int y1 = (int) (y - len * Math.sin(Math.PI / 2 - e));

            xList.add(x1);
            yList.add(y1);

            //右子树
            int lenRight = len * 3 / 4;
            int x2 = x + (x1 - x) / 3;
            int y2 = y - (y - y1) / 3;
            double e1 = e + Math.PI / 6;

            //左子树
            int lenLeft = len * 3 / 4;
            int x3 = x + (x1 - x) * 2 / 3;
            int y3 = y - (y - y1) * 2 / 3;
            double e2 = e - Math.PI / 6;

            getPoint(x2, y2, lenRight, e1);
            getPoint(x3, y3, lenLeft, e2);
        }
    }
}
